package com.jx.lcs.util.export;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

/**
 * 导出 excel
 * <p>
 * 使用 Bean 渲染数据
 * 
 * 示例_1，输出一个 sheet: <br/>
 * List<Bean> dataSet = new ArrayList<>(); <br/>
 * ...装配数据
 * 
 * SheetDefination<Bean> defination = new SheetDefination<>(); <br/>
 * defination.setSheetTitle("sheet标题"); <br/>
 * defination.setHeaders(new String[] {"header_1", "header_2", "header_3"}); <br/>
 * defination.setDataKeys(new String[] {"key_1", "key_2", "key_3"}); <br/>
 * defination.setDataset(dataSet); <br/>
 * defination.setBeanClass(Bean.class);
 * 
 * ExportExcel4Bean<Bean> exportExcel = new ExportExcel4Bean<Bean>(); <br/>
 * OutputStream out = new FileOutputStream("E://a.xls"); <br/>
 * exportExcel.export(defination, out); <br/>
 * out.close();
 * 
 * 示例_2，输出 多个 sheet: <br>
 * List<Bean> dataSet_1 = new ArrayList<>(); <br/>
 * ... <br/>
 * List<Bean> dataSet_n = new ArrayList<>();
 * 
 * SheetDefination<Bean> defination_1 = new SheetDefination<>(); <br/>
 * ... <br/>
 * SheetDefination<Bean> defination_n = new SheetDefination<>(); <br/>
 * ...
 * 
 * List<SheetDefination<Bean>> definationList = new ArrayList<>(); <br/>
 * definationList.add(defination_1); <br/>
 * ... <br/>
 * definationList.add(defination_n);
 * 
 * ExportExcel4Bean<Bean> exportExcel = new ExportExcel4Bean<Bean>(); <br/>
 * OutputStream out = new FileOutputStream("E://b.xls"); <br/>
 * exportExcel.export(definationList, out); <br/>
 * out.close();
 * 
 * @author sunlt
 * @date 2015.07.15
 *
 * @param <T> Bean类型
 */
public class Excel4BeanExporter<T> extends ExcelExporter<T> {

  /**
   * 时间格式
   */
  private String timePattern;

  /**
   * 渲染数据
   * 
   * @param workbook 工作簿
   * @param sheet 单
   * @param defination sheet定义
   */
  @Override
  protected void renderData(HSSFWorkbook workbook, HSSFSheet sheet, SheetDefination<T> defination) {

    String[] datakeys = defination.getDataKeys();
    Field[] fields = new Field[datakeys.length];
    boolean getFieldsComplete = false;
    Iterator<T> dataIterator = defination.getDataset().iterator();
    SimpleDateFormat dateFormat = this.getDateFormat();

    try {
      for (int i = 0; i < datakeys.length; i++) {
        fields[i] = defination.getBeanClass().getDeclaredField(datakeys[i]);
      }
      AccessibleObject.setAccessible(fields, true);
      getFieldsComplete = true;

      HSSFRow row;
      int index = 0;
      while (dataIterator.hasNext()) {
        index++;
        row = sheet.createRow(index);

        T element = dataIterator.next();
        for (int i = 0; i < fields.length; i++) {
          HSSFCell cell = row.createCell(i);
          cell.setCellStyle(createDataStyle(workbook));
          HSSFRichTextString text =
              new HSSFRichTextString(
                  fields[i].get(element) instanceof Date ? dateFormat.format(fields[i].get(element))
                      : String.valueOf(fields[i].get(element)));
          cell.setCellValue(text);
        }
      }

    } catch (Exception e) {

      e.printStackTrace();
      throw new RuntimeException("数据渲染出错！");

    } finally {

      if (getFieldsComplete) {
        AccessibleObject.setAccessible(fields, false);
      }

    }
  }

  /**
   * 获取时间格式化对象
   */
  private SimpleDateFormat getDateFormat() {
    return this.timePattern == null ? new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
        : new SimpleDateFormat(this.timePattern);
  }

  public void setTimePattern(String timePattern) {
    this.timePattern = timePattern;
  }

}
